/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package aspect.example;
import aspect.util.Complex;
import aspect.util.Trig;
import static aspect.example.AspectTest.r;
import aspect.util.Vector2;
import java.util.Arrays;
/**
*
* @author millerv
*/
public class FFTTest {
public static void generateTerrain(float[][] floats, int w) {
for (int i = 0; i < w; i++) {
for (int j = 0; j < w; j++) {
floats[i][j] = r.nextFloat() * 2 - 1;
}
}
Complex[][] comp = new Complex[w][w];
for (int i = 0; i < w; i++) {
for (int j = 0; j < w; j++) {
comp[i][j] = new Complex(floats[i][j], 0);
}
}
fft2(comp, w);
//modify2(comp, w);
//ifft2(comp, w);
for (int i = 0; i < w; i++) {
for (int j = 0; j < w; j++) {
floats[i][j] = comp[i][j].real;
}
}
}
public static void modify2(Complex[][] comp, int w) {
Vector2 center = new Vector2(w / 2, w / 2);
for (int i = 0; i < w; i++) {
for (int j = 0; j < w; j++) {
Vector2 pos = new Vector2(i, j);
float f = Vector2.distance(pos, center) + 1;
comp[i][j].real /= f;
//comp[i][j].real *= 20;
comp[i][j].imaginary /= f;
//comp[i][j].imaginary *= 20;
}
}
}
public static void fft2(Complex[][] comp, int w) {
Complex[][] dest = new Complex[w][w];
Complex[] c = new Complex[w];
for (int i = 0; i < w; i++) {
System.arraycopy(comp[i], 0, c, 0, w);
fft(c);
System.arraycopy(c, 0, dest[i], 0, w);
}
for (int j = 0; j < w; j++) {
for (int i = 0; i < w; i++) {
c[i] = dest[i][j].copy();
}
fft(c);
for (int i = 0; i < 10; i++) {
dest[i][j] = c[i];
}
}
for (int i = 0; i < w; i++) {
System.arraycopy(dest[i], 0, comp[i], 0, w);
}
}
public static void ifft2(Complex[][] comp, int w) {
Complex[][] dest = new Complex[w][w];
Complex[] c = new Complex[w];
for (int i = 0; i < w; i++) {
System.arraycopy(comp[i], 0, c, 0, w);
ifft(c);
System.arraycopy(c, 0, dest[i], 0, w);
}
for (int j = 0; j < w; j++) {
for (int i = 0; i < w; i++) {
c[i] = dest[i][j].copy();
}
ifft(c);
for (int i = 0; i < 10; i++) {
dest[i][j] = c[i];
}
}
for (int i = 0; i < w; i++) {
System.arraycopy(dest[i], 0, comp[i], 0, w);
}
}
public static void modify(Complex[] c) {
int n = c.length / 2;
for (int i = 0; i < c.length; i++) {
//c[i].real = 0;
c[i].real /= Math.abs(i - n) + 1;
c[i].imaginary /= Math.abs(i - n) + 1;
//c[i].imaginary = 0;
}
}
public static float[] toFloat(Complex[] c) {
float[] f = new float[c.length];
for (int i = 0; i < c.length; i++) {
f[i] = c[i].real;
}
return f;
}
public static Complex[] toComplex(float[] f) {
Complex[] c = new Complex[f.length];
for (int i = 0; i < f.length; i++) {
c[i] = new Complex(f[i], 0);
}
return c;
}
public static void fft(Complex[] c) {
int l = c.length;
if (l == 1) {
return;
} else if (l % 2 != 0) {
throw new RuntimeException("Not a power of two!");
}
Complex[] even = new Complex[l / 2];
Complex[] odd = new Complex[l / 2];
for (int i = 0; i < l / 2; i++) {
even[i] = c[2 * i];
odd[i] = c[2 * i + 1];
}
fft(even);
fft(odd);
for (int i = 0; i < l / 2; i++) {
float kth = Trig.toDegrees(-2 * i * Trig.PI / l);
Complex wk = new Complex(Trig.cos(kth), Trig.sin(kth));
c[i] = even[i].plus(wk.times(odd[i]));
c[i + l / 2] = even[i].minus(wk.times(odd[i]));
}
}
public static void ifft(Complex[] c) {
int l = c.length;
for (int i = 0; i < l; i++) {
c[i] = c[i].conjugate();
}
fft(c);
for (int i = 0; i < l; i++) {
c[i] = c[i].conjugate().times(1.0f / l);
}
}
}